package com.senyint.hip.fhir.web;

import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.client.impl.GenericClient;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.senyint.hip.fhir.interceptor.CaptureInterceptor;
import org.hl7.fhir.r4.model.*;
import org.hl7.fhir.exceptions.FHIRException;
import org.springframework.web.bind.annotation.*;


/**
 * *******description*******
 * 检验报告
 * *************************
 *
 * @author ChenPan
 * @date 2018/10/31 10:14
 */
@RestController
@RequestMapping("/labReport")
public class LabReportController extends FhirBaseController {

    @PostMapping()
    public String createReport(@RequestBody String reportStr) throws FHIRException {
        DiagnosticReport dr = convertDr(reportStr);

        CaptureInterceptor interceptor = new CaptureInterceptor();
        GenericClient client = newClient(tempData.getBaseServer(), interceptor);

        MethodOutcome out = client.create().resource(dr).execute();

        return new Gson().toJson(out);

    }

    @PutMapping("/{id}")
    public String updateReport(@PathVariable("id") String id, @RequestBody String reportStr) throws FHIRException {
        DiagnosticReport dr = convertDr(reportStr);

        CaptureInterceptor interceptor = new CaptureInterceptor();
        GenericClient client = newClient(tempData.getBaseServer(), interceptor);

        MethodOutcome out = client.update(id, dr);

        return new Gson().toJson(out);

    }

    protected DiagnosticReport convertDr(String reportStr) {
        JSONObject report = JSON.parseObject(reportStr);
        DiagnosticReport dr = new DiagnosticReport();

        dr.addIdentifier(new Identifier().setValue(report.getString("identifier")));
        dr.setSubject(new Reference().setDisplay(report.getString("patientName")));
        dr.setEffective(new DateTimeType(report.getDate("effectiveDateTime")));
        dr.setIssued(report.getDate("issued"));
        CodeableConcept item = new CodeableConcept();
        item.addCoding(new Coding().setSystem("http://loinc.org")
                .setCode(report.getString("code"))
                .setDisplay(report.getString("display"))
        ).setText(report.getString("text"));
        dr.setCode(item);


        JSONArray subItem = report.getJSONArray("subItem");
        for (int i = 0; i < subItem.size(); i++) {
            JSONObject sub = subItem.getJSONObject(i);

            Observation ob = new Observation();
            //标本
            ob.setSpecimen(new Reference().setDisplay(report.getString("sample")));
            /* ob.setId(sub.getString("no"));*/
            ob.setStatus(Observation.ObservationStatus.FINAL);
            ob.getCode().addCoding().setSystem("http://loinc.org")
                    .setCode(sub.getString("code"))
                    .setDisplay(sub.getString("display"));
            ob.setSubject(new Reference().setDisplay(report.getString("patientName")));
            ob.addPerformer(new Reference().setDisplay(report.getString("tester")));
            ob.setValue(new Quantity()
                    .setValue(sub.getDouble("value"))
                    .setUnit(sub.getString("unit")));
            SimpleQuantity low = new SimpleQuantity();
            if (sub.get("low") != null && !"".equals(sub.getString("low"))) {

                low.setValue(sub.getDouble("low"));
            }
            low.setUnit(sub.getString("unit"));

            SimpleQuantity high = new SimpleQuantity();
            if (sub.get("high") != null && !"".equals(sub.getString("high"))) {

                high.setValue(sub.getDouble("high"));
            }
            high.setUnit(sub.getString("unit"));

            ob.addReferenceRange(new Observation.ObservationReferenceRangeComponent().setLow(low).setHigh(high));


            /*dr.getContained().add(ob);*/
            /*dr.addContained(ob);*/
            dr.addResult(new Reference(ob));
            
        }

        return dr;
    }
}
